package cn.zlj.nmcc.service.impl;

import cn.zlj.nmcc.domain.*;
import cn.zlj.nmcc.dto.CourseDto;
import cn.zlj.nmcc.dto.MessageSmsDto;
import cn.zlj.nmcc.dto.UserSmsDto;
import cn.zlj.nmcc.exception.GlobalExceptionCodeEnum;
import cn.zlj.nmcc.mapper.CourseMapper;
import cn.zlj.nmcc.mapper.CourseTypeMapper;
import cn.zlj.nmcc.mqconstants.MqConstants;
import cn.zlj.nmcc.result.JSONResult;
import cn.zlj.nmcc.service.*;
import cn.zlj.nmcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static cn.zlj.nmcc.mqconstants.MqConstants.COURSE_SMS_TOPIC;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zlj
 * @since 2022-11-21
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private ICourseDetailService courseDetailService;

    @Autowired
    private ITeacherService teacherService;

    @Autowired
    private ICourseMarketService courseMarketService;

    @Autowired
    private ICourseResourceService courseResourceService;

    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private CourseEsService courseEsService;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    @Transactional
    public void save(CourseDto courseDto) {
        //参数校验
        //业务校验。。课程名不能一样
        extracted(courseDto);
        Course course = courseDto.getCourse();
        CourseDetail courseDetail = courseDto.getCourseDetail();
        CourseMarket courseMarket = courseDto.getCourseMarket();
        CourseResource courseResource = courseDto.getCourseResource();
        List<Long> teacherIds = courseDto.getTeacherIds();
        // 3.保存课程
        saveCourse(course, teacherIds);
        // 3.1.新增之后返回主键ID
        Long courseId = course.getId();
        // 4.保存详情信息
        courseDetail.setId(courseId);
        courseDetailService.insert(courseDetail);
        // 5.保存营销信息
        courseMarket.setId(courseId);
        courseMarketService.insert(courseMarket);
        // 6.保存资源信息
        courseResource.setCourseId(courseId);
        courseResourceService.insert(courseResource);
        // 7.初始化课程统计信息
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(courseId);
        courseSummaryService.insert(courseSummary);
        // 8.保存讲师中间表信息
        courseMapper.insertCourseTeacher(courseId, teacherIds);
        // 9.给对应课程类型数量加一
        courseTypeMapper.updateTotalCountById(course.getCourseTypeId());
    }

    @Override
    public void onLineCourse(Long id) {
        Course course = selectById(id);
        AssertUtil.isNotNull(course,GlobalExceptionCodeEnum.UAA_PARAM_IS_NULL);
        //上架
       if(course.getStatus()!=1) course.setStatus(1);
         updateById(course);
        // 4.设置CourseDoc数据
        // 4.1.查询数据
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        CourseMarket courseMarket = courseMarketService.selectById(course.getId());
        CourseSummary courseSummary = courseSummaryService.selectById(course.getId());
        // 4.2.拷贝数据到doc对象中
        CourseDoc courseDoc = new CourseDoc();
        BeanUtils.copyProperties(course, courseDoc);
        BeanUtils.copyProperties(courseMarket, courseDoc);
        //BeanUtils.copyProperties(courseSummary, courseDoc);
        // 4.3.不能拷贝的字段单独设置
        courseDoc.setCourseTypeName(courseType.getName());
        String charge = courseMarket.getCharge()==1?"免费":"收费";
        courseDoc.setCharge(charge);

        // 5.调用搜索服务，进行课程信息存储，此处我们直接传递要保存到ES中的doc对象
        JSONResult jsonResult = courseEsService.saveEs(courseDoc);
        // 5.1.判断课程如果发布失败，那么抛出异常
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.ERROR);

        sendMessage(courseDoc);

    }
    private void sendMessage(CourseDoc courseDoc) {
        // 1.初始化消息对象
        MessageSmsDto messageSmsDto = new MessageSmsDto();
        messageSmsDto.setTitle("课程发布");
        messageSmsDto.setContent("亲爱的用户您好，最新课程 <a href='localhost:6002/list.html?courseId="+courseDoc.getId()+"'> 测试 </a> 发布啦，点击课程了解详情");
        // @TODO 此处应该查询所有的要发短信的用户的对象信息
        List<UserSmsDto> userSmsDtos = Arrays.asList(
                new UserSmsDto(1L, "13330964748"),
                new UserSmsDto(2L, "18000534099")
        );
        messageSmsDto.setUsers(userSmsDtos);
        rocketMQTemplate.sendOneWay(MqConstants.COURSE_SMS_TOPIC + ":" + MqConstants.COURSE_SMS_TAG, JSON.toJSONString(messageSmsDto));
    }

    private void saveCourse(Course course, List<Long> teacherIds) {
        //初始化参数
        //设置初始状态为下架
        course.setStatus(Course.STATUS_OFFLINE);

        course.setLoginId(6L);
        course.setLoginUserName("ls");
        // 讲师需要查询之后进行讲师名称设置
        List<Teacher> teachers = teacherService.selectBatchIds(teacherIds);
        // 得到讲师名称使用逗号进行拼接
        String teacherStr = teachers.stream().map(Teacher::getName).collect(Collectors.joining(","));
        course.setTeacherNames(teacherStr);
        // 2.保存课程信息
        insert(course);
    }

    private void extracted(CourseDto courseDto) {
        Wrapper<Course> wrapper=new EntityWrapper<>();
        wrapper.eq("name", courseDto.getCourse().getName());
        Course one = super.selectOne(wrapper);
        AssertUtil.isNull(one, GlobalExceptionCodeEnum.COURSE_NAME_ALREADY_EXISTS);
    }
}
